home *** CD-ROM | disk | FTP | other *** search
/ TPUG - Toronto PET Users Group / TPUG Users Group CD / TPUG Users Group CD.iso / AMIGA / AMICUS / AMICUS01.ADF / C / cc.c < prev    next >
Text File  |  1985-12-04  |  20KB  |  621 lines

  1. /*
  2. Path: puff!uwvax!seismo!lll-crg!lll-lcc!unisoft!fnf
  3. From: fnf@unisoft.UUCP
  4. Subject: cc.c (unix like Lattice C frontend)
  5. Date: 23 Nov 85 07:11:04 GMT
  6. Organization: UniSoft Systems, Berkeley
  7.  
  8. As I promised in one of my earlier postings, enclosed is the source to my
  9. unix like front end for the Lattice C compiler.  This is real useful
  10. for most simple C programs without any amiga specific compilation or
  11. linking requirements.
  12.  
  13. One of the features of this cc is that your development disk can be in
  14. any drive, including ram, and cc will find it.
  15.  
  16. Does anyone know of a secret flag to get the Lattice compiler to emit
  17. assembly language?  How about a flag to turn off those obnoxious
  18. startup messages (I'm going to patch my compiler if necessary!).
  19.  
  20. Anyway, hope you find this useful.  I was going to post a version of
  21. DECUS grep also, but looks like someone beat me to it.
  22.  
  23. -Fred           (415) 644-1230
  24. */
  25.  
  26. /************************************************************************
  27.  *                                                                      *
  28.  *                      Copyright (c) 1985, Fred Fish                   *
  29.  *                          All Rights Reserved                         *
  30.  *                                                                      *
  31.  *      This software and/or documentation is released into the         *
  32.  *      public domain for personal, non-commercial use only.            *
  33.  *      Limited rights to use, modify, and redistribute are hereby      *
  34.  *      granted for non-commercial purposes, provided that all          *
  35.  *      copyright notices remain intact and all changes are clearly     *
  36.  *      documented.  The author makes no warranty of any kind with      *
  37.  *      respect to this product and explicitly disclaims any implied    *
  38.  *      warranties of merchantability or fitness for any particular     *
  39.  *      purpose.                                                        *
  40.  *                                                                      *
  41.  ************************************************************************
  42.  */
  43.  
  44.  
  45.  
  46. /*
  47.  *      cc -- C compiler front end for Amiga and Lattice C.
  48.  *
  49.  *      Somewhat AMIGA/Lattice dependent, but can probably be adapted to
  50.  *      other systems with a minimum of work.  I have attempted to keep
  51.  *      portability in mind as much as possible.
  52.  *
  53.  */
  54.  
  55. char _sccsid[] = "@(#)cc.c      1.3";
  56.  
  57. #include <stdio.h>
  58.  
  59. /*
  60.  *      The following allow use on systems that don't have my macro based
  61.  *      debugging package.  The default, for now, is to assume it is not
  62.  *      available.
  63.  */
  64.  
  65. #ifdef DBUG
  66. #  include <local/dbug.h>
  67. #else   /* !DBUG */
  68. #  define DBUG_ENTER(a)
  69. #  define DBUG_RETURN(a) return(a)
  70. #  define DBUG_VOID_RETURN return
  71. #  define DBUG_2(a,b)
  72. #  define DBUG_3(a,b,c)
  73. #  define DBUG_4(a,b,c,d)
  74. #  define DBUG_5(a,b,c,d,e)
  75. #  define DBUG_PUSH(a)
  76. #endif  /* DBUG */
  77.  
  78. /*
  79.  *      Manifest constants which can be tuned to fit requirements.
  80.  */
  81.  
  82. #define CMDBUFFERSIZE (256)     /* Size of command buffer for CLI command */
  83. #define MAXOPERANDS (64)        /* Maximum number of operands on cmd line */
  84. #define MAXDEFINES (32)         /* Maximum number of -D<name> args */
  85. #define MAXUNDEFINES (32)       /* Maximum number of -U<name> args */
  86. #define MAXINCDIRS (16)         /* Maximum number of -I<filename> args */
  87. #define MAXLIBS (16)            /* Maximum number of -l<lib> args */
  88.  
  89. /*
  90.  *      Define QUADDEV to be the place where you want the compiler
  91.  *      intermediate files (quad files) to be created.  For systems with
  92.  *      512K or more, the preferred place is the ram disk.  However,
  93.  *      really big compiles may need to be done on a hard disk.
  94.  */
  95.  
  96. #define QUADDEV "ram:"          /* Keep intermediate files in ram */
  97. /* #define QUADDEV "" */        /* Keep intermediate files in current dir */
  98.  
  99. /*
  100.  *      Manifest constants which are generally the same on all systems.
  101.  */
  102.  
  103. #define EOS '\000'              /* End of string character */
  104.  
  105. /*
  106.  *      Command line arguments that represent files to be compiled, assembled,
  107.  *      or linked, are kept track of via an "Operand" array.  If, for example,
  108.  *      the file name is "df0:mydir/junk.c", then the Rootname is
  109.  *      "df0:mydir/junk", the Basename is "junk", and the Suffix is "c".
  110.  *      String suffixes are used, rather than single character suffixes, to
  111.  *      allow use of names with multicharacter suffixes.
  112.  */
  113.  
  114. struct Operand {                /* Info about each operand (non option) */
  115.     char *Rootname;             /* Name minus any suffix */
  116.     char *Basename;             /* Name minus any prefix or suffix */
  117.     char *Suffix;               /* Suffix of operand */
  118. };
  119.  
  120. static struct Operand Operands[MAXOPERANDS];    /* Table of operands */
  121. static int NOperands = 0;                       /* Number of operands found */
  122. static char *Defines[MAXDEFINES];               /* Table of defines */
  123. static int NDefines = 0;                        /* Number of defines */
  124. static char *UnDefines[MAXUNDEFINES];           /* Table of undefines */
  125. static int NUnDefines = 0;                      /* Number of undefines */
  126. static char *UserInc[MAXINCDIRS];               /* Table of include dirs */
  127. static int NUserInc = 0;                        /* Number of include dirs */
  128. static char *Libs[MAXLIBS];                     /* Table of library args */
  129. static int NLibs = 0;                           /* Number of library args */
  130.  
  131. /*
  132.  *      Macros to determine the suffix type of a file given a pointer to
  133.  *      its operand structure.
  134.  */
  135.  
  136. #define CFILE(op) (strcmp(op->Suffix,"c")==0)
  137. #define SFILE(op) (strcmp(op->Suffix,"s")==0)
  138. #define OFILE(op) (strcmp(op->Suffix,"o")==0)
  139.  
  140. #ifdef AMIGA
  141. #  define system(a) (Execute(a,0,0))
  142. #  define ENABLE_ABORT (Enable_Abort = 1)
  143. #  define DISABLE_ABORT (Enable_Abort = 0)
  144. extern int Enable_Abort;                        /* Enable abort on CNTL-C */
  145. #else
  146. #  define ENABLE_ABORT                          /* Null expansion */
  147. #  define DISABLE_ABORT                         /* Null expansion */
  148. #endif  /* AMIGA */
  149.  
  150. /*
  151.  *      Set list of places to search for various executables, libraries, etc.
  152.  *      Searched in order, first match wins.
  153.  */
  154.  
  155. static char *Devices[] = {
  156.     "",
  157.     "ram:",
  158.     "df0:",
  159.     "df1:",
  160.     NULL
  161. };
  162.  
  163. static char *BinDirs[] = {
  164.     "",
  165.     "ram:c/",
  166.     "df0:c/",
  167.     "df1:c/",
  168.     NULL
  169. };
  170.  
  171. static char *LibDirs[] = {
  172.     "",
  173.     "ram:lib/",
  174.     "df0:lib/",
  175.     "df1:lib/",
  176.     NULL
  177. };
  178.  
  179. static char *IncDirs[] = {
  180.     "ram:include/",
  181.     "df0:include/",
  182.     "df1:include/",
  183.     NULL
  184. };
  185.  
  186. /*
  187.  *      Flags set by command line arguments/
  188.  */
  189.  
  190. static int cflag;                       /* -c flag given */
  191. static int Pflag;                       /* -P flag given */
  192. static int Sflag;                       /* -S flag given */
  193. static int Vflag;                       /* -V flag given (non-standard) */
  194.  
  195. static int ErrCount = 0;                /* Count of compile/assemble errors */
  196. static char *outfile = "a.out";         /* Output file name from linker */
  197. static char *QuadDev = QUADDEV;         /* Where to keep quad files */
  198.  
  199. static char *Locate ();                 /* Find a file */
  200. static void Check_Abort ();             /* Test for abort requested */
  201. static void Fatal ();                   /* Quit with fatal error */
  202. static void Warning ();                 /* Issue warning message */
  203. static void AddOperandToList ();        /* Add .c, .s, or .o file to list */
  204. static void MakeObjects ();             /* Reduce to list of object files */
  205. static void ParseCommandLine ();        /* Deal with command line */
  206. static void Compile ();                 /* Translate from .c to .o */
  207. static void Assemble ();                /* Translate from .s to .o */
  208. static void Link ();                    /* Gather .o's into executable */
  209.  
  210. extern void exit ();                    /* See exit(2) */
  211.  
  212. main (argc, argv)
  213. int argc;
  214. char *argv[];
  215. {
  216.     DBUG_ENTER ("main");
  217.     ENABLE_ABORT;
  218.     ParseCommandLine (argc, argv);
  219.     MakeObjects ();
  220.     if (!cflag && !Pflag && !Sflag && ErrCount == 0) {
  221.         Link ();
  222.     }
  223.     DBUG_RETURN (0);
  224. }
  225.  
  226. /*
  227.  *      The following macro is used to allow optional whitespace between
  228.  *      an option and it's argument.  Argp is left pointing at the option
  229.  *      and argv and argc are adjusted accordingly if necessary.
  230.  *
  231.  *      Note that there is no check for missing option arguments.  In
  232.  *      particular, -o -V will blindly take -V as the output file name.
  233.  *
  234.  */
  235.  
  236. #define XARG(argc,argv,argp) {if(*++argp==EOS){argp=(*argv++);argc--;}}
  237.  
  238. static void ParseCommandLine (argc, argv)
  239. int argc;
  240. char **argv;
  241. {
  242.     register char *argp;    
  243.  
  244.     DBUG_ENTER ("ParseCommandLine");
  245.     argc--;
  246.     argv++;
  247.     while (argc-- > 0) {
  248.         Check_Abort ();
  249.         argp = *argv++;
  250.         if (*argp != '-') {
  251.             AddOperandToList (argp);
  252.         } else {
  253.             switch (*++argp) {
  254.                 case '#':
  255.                     XARG (argc, argv, argp);
  256.                     DBUG_PUSH (argp);
  257.                     break;
  258.                 case 'c':
  259.                     cflag++;
  260.                     break;
  261.                 case 'D':
  262.                     XARG (argc, argv, argp);
  263.                     if (NDefines >= MAXDEFINES) {
  264.                         Fatal ("too many -D args (%d max)", MAXDEFINES);
  265.                     }
  266.                     Defines[NDefines++] = argp;
  267.                     break;
  268.                 case 'E':
  269.                     Warning ("-E unimplemented, converted to -P instead");
  270.                     Pflag++;
  271.                     break;
  272.                 case 'f':
  273.                     break;      /* NOP for now, just eat it */
  274.                 case 'g':
  275.                     break;      /* NOP for now, just eat it */
  276.                 case 'I':
  277.                     XARG (argc, argv, argp);
  278.                     if (NUserInc >= MAXINCDIRS) {
  279.                         Fatal ("too many -I args (%d max)", MAXINCDIRS);
  280.                     }
  281.                     UserInc[NUserInc++] = argp;
  282.                     break;
  283.                 case 'l':
  284.                     XARG (argc, argv, argp);
  285.                     if (NLibs > MAXLIBS) {
  286.                         Fatal ("too many -l args (%d max)", MAXLIBS);
  287.                     }
  288.                     Libs[NLibs++] = argp;
  289.                     break;
  290.                 case 'O':
  291.                     break;      /* NOP for now, just eat it */
  292.                 case 'o':
  293.                     XARG (argc, argv, argp);
  294.                     outfile = argp;
  295.                     break;
  296.                 case 'P':
  297.                     Pflag++;
  298.                     break;
  299.                 case 'q':
  300.                     XARG (argc, argv, argp);
  301.                     QuadDev = argp;
  302.                     break;
  303.                 case 'S':
  304.                     Sflag++;
  305.                     Warning ("-S option not yet implemented, ignored");
  306.                     break;
  307.                 case 's':
  308.                     break;              /* NOP for now, just eat it */
  309.                 case 'U':
  310.                     XARG (argc, argv, argp);
  311.                     if (NUnDefines >= MAXUNDEFINES) {
  312.                         Fatal ("too many -U args (%d max)", MAXUNDEFINES);
  313.                     }
  314.              /* how to use the ffp library, text and source */
  315.  
  316. #ifdef FOOIE
  317.  
  318. From: bobp@amiga.UUCP (Robert S. Pariseau)
  319. Subject: Amiga Floating Point
  320. Date: 1 Nov 85 04:58:43 GMT
  321.  
  322. Floating point support exists on the Amiga in several forms for several 
  323. purposes.  The floating point which is directly supported by expression 
  324. evaluation in the V1.0 release Lattice C for the Amiga is a 64 bit software 
  325. implementation of the IEEE format.  As such, it is *>SLOW<*.
  326.  
  327. The floating point in ABasiC is a 32
  328.         {
  329.                 fread(buf,sizeof(buf),1,in);
  330.                 for(i=0,j=0; buf[i] != '\n' && buf[i] != 'Q' && i < sizeof(buf); i++)
  331.                   {
  332.                         bytes[j] = (cnv(buf[i++]) << 4);
  333.                         bytes[j++] |= cnv(buf[i]);
  334.                   }
  335.                 write(out,bytes,j);
  336.                 if (buf[i] == 'Q')
  337.                   break;
  338.         }
  339.   fclose(in);
  340.   close(out);
  341. }
  342.  
  343.  
  344. int cnv(ch)
  345. char ch;
  346. {
  347.   if (ch >= '0' && ch <= '9')
  348.     return(ch-'0');
  349.   else
  350.     return((ch-'A')+10);
  351. }
  352. /* value */
  353.                                                 putit(j);
  354.                                                 break;
  355.                                         case 129: /* ext_ref32 */
  356.                                         case 131: /* ext_ref16 */
  357.                                         case 132: /* ext_ref8  */
  358.                                                 for(i=0; i < lbuf; i++)
  359.                                               3210/╙FExample, doc for expand.o routines to expand wildcard file expressions ;yechox.cü¢   ²/* expand.doc, echox.c */
  360.  
  361.  
  362. #ifdef FOOIE
  363.  
  364. The file EXPAND.O is the object for a group of subroutines which
  365. expand wild card filenames for AMIGA DOS.  The wild card syntax
  366. is similar to unix and implements *, ? and [] type syntax e.g.
  367.  
  368.  
  369.         *.c             /* anything ending in .c */
  370.         ???.a?          /* anything beginning with any three characters,
  371.                            followed by a . followed by 'a' followed by
  372.                            any single character */
  373.  
  374.     
  375. /* objfix.c */
  376.  
  377. /****************************************************************/
  378. /* Fixup routine for object files output from Lattice C         */
  379. /* makes external symbols available to Wack!                    */
  380. /*                                                              */
  381. /* part of the Amiga Programmer's Library                       */
  382. /* Note, originally compiled with microsoft C 3.0 for the PC    */
  383. /*                                                              */
  384. /*      Copyright (c) 1985 by Michael G. Lehman, MaxiCorp       */
  385. /*      All rights reserved, posted on bulletin boards by       */
  386. /*      permission.                                             */
  387. /****************************************************************/
  388.  
  389. /* define the right symbols for your C compiler and environment */
  390.  
  391. #define LATTI
  392. #undef MSC30
  393.  
  394.  
  395. #include <stdio.h>
  396. #include <fcntl.h>
  397.  
  398. /* these are needed for Microsoft C v3.0 */
  399. #ifdef MSC30
  400. #include <sys\types.h>  /*included so sys\stat.h works */
  401. #include <sys\stat.h>   /* included to get S_IREAD && S_IWRITE */
  402. #define O_RAW O_BINARY
  403. #endif
  404.  
  405. struct {
  406.      unsigned long len;         /* symbol table field length */
  407.      unsigned long sym[40];     /* 160 chars max */
  408.      unsigned long value;
  409. } symhunk[100];                 /* allow for 100 symbols */
  410.  
  411. int nxtsym;
  412. int width;
  413. long startoffset;
  414. int f;
  415.  
  416. main(argc,argv)
  417. int argc;
  418. char **argv;
  419. {
  420.   int infile;
  421.   long l;
  422.   unsigned long i,j;
  423.   int open();
  424.   char *fname;
  425.   unsigned long lbuf;
  426.   int debug;
  427.   unsigned char typ;
  428.  
  429.   if (argc < 2)
  430.     {
  431.         printf("Usage: objfix <cnvfile>\n");
  432.         exit(0);
  433.     }
  434.  
  435.   debug = (argc > 2);
  436.  
  437.   fname = argv[1];
  438.  
  439.   if (!*fname)
  440.     return(0);
  441.  
  442.   infile = open(fname,0);
  443.  
  444.   if (infile == -1)
  445.     {
  446.       printf("\n\nUnable to open \"%s\" for dumping\n",fname);
  447.       exit(10);
  448.     }
  449.  
  450. #ifdef MSC30
  451.   f = creat("cnv.tmp",S_IREAD | S_IWRITE);       /* assume binary mode */
  452. #endif
  453. #ifdef LATTI
  454.   f = creat("cnv.tmp", O_RAW | O_RDWR );       /* assume binary mode */
  455. #endif
  456.  
  457.   printf("\nConverting file: \"%s\" \n\n",fname);
  458.  
  459.   nxtsym = 0;
  460.  
  461.   while(1)
  462.     {
  463.       l = read(infile,&lbuf,4);
  464.       if (l!=4)
  465.         break;
  466.       if (lbuf != 0xF2030000)
  467.         putit(lbuf);
  468.       normalize(&lbuf);
  469.       if (debug)
  470.         printf("Block type: 0x%x\n",lbuf);
  471.  
  472.       switch(lbuf)
  473.         {
  474.                 case 0x3E7:     /* hunk_unit */
  475.                 case 0x3E8:     /* hunk_name */
  476.                 case 0x3E9:     /* hunk_code */
  477.                 case 0x3EA:     /* hunk_data */
  478.                                 read(infile,&lbuf,4);
  479.                                 putit(lbuf);
  480.                                 normalize(&lbuf);
  481.                                 for(i=0; i < lbuf; i++)
  482.                                   {
  483.                                     read(infile,&j,4);
  484.                                     putit(j);
  485.                                   }
  486.                                 break;
  487.  
  488.                 case 0x3EB:     /* hunk_bss */
  489.                                 read(infile,&lbuf,4);
  490.                                 putit(lbuf);
  491.                                 break;
  492.  
  493.                 case 0x3EC:     /* hunk_r32 */
  494.                 case 0x3ED:     /* hunk_r16 */
  495.                 case 0x3EE:     /* hunk_r8  */
  496.                                 read(infile,&lbuf,4);
  497.                                 putit(lbuf);
  498.                                 read(infile,&j,4);      /* hunk_number */
  499.                                 putit(j);
  500.                                 normalize(&lbuf);
  501.                                 while(lbuf)
  502.                                   {
  503.                                     for(i=0; i < lbuf; i++)
  504.                                       {
  505.                                         read(infile,&j,4);
  506.                                         putit(j);
  507.                                       }
  508.                                    d(mywindow->RPort,COMPLEMENT);
  509. SetAPen(mywindow->RPort,3);
  510. RectFill(mywindow->RPort,cx-7,cy-6,cx,cy+1);
  511. SetAPen(mywindow->RPort,1);
  512. SetDrMd(mywindow->RPort,JAM2);
  513.  
  514. if (x > (xmax-31))
  515.    {
  516.    x = 3;
  517.    y += 8;
  518.    }
  519.  
  520. if (y > (ymax-2))
  521.    {
  522.    x = 3;
  523.    y -= 8;
  524.    }
  525.  
  526. Move(mywindow->RPort,x,y);
  527.  
  528. switch( c )
  529.       {
  530.       case '\t':
  531.          x += 60;
  532.          break;
  533.       case '\n':
  534.          break;
  535.       case 13:  /* newline */
  536.          x = 3;
  537.          y += 8;
  538.          break;
  539.       case 8:   /* backspace */
  540.          x -= 8;
  541.          if (x < 3)
  542.             x = 3;
  543.          break;
  544.       case 12:     /* page */
  545.          x = 3;
  546.          y = 17;
  547.          SetAPen(mywindow->RPort,0);
  548.          RectFill(mywindow->RPort,2,10,xmax-19,ymax-7);
  549.          SetAPen(mywindow->RPort,1);
  550.          break;
  551.       case 7:     /* bell */
  552.          ClipBlit(mywindow->RPort,0,0,mywindow->RPort,0,0,xmax,ymax,0x50);
  553.          ClipBlit(mywindow->RPort,0,0,mywindow->RPort,0,0,xmax,ymax,0x50);
  554.          break;
  555.       default:
  556.          Text(mywindow->RPort,&c,1);
  557.          x += 8;
  558.       } /* end of switch */
  559. /* cursor */
  560. if (x > (xmax-31))
  561.    {
  562.    cx = 9;
  563.    cy = y + 8;
  564.    }
  565. else
  566.   {
  567.   cx = x+8;
  568.   cy = y;
  569.   }
  570.  
  571. if (cy > (ymax-2))
  572.    {
  573.    cx = 9;
  574.    cy -= 8;
  575.    ScrollRaster(mywindow->RPort,0,8,2,10,xmax-20,ymax-2);
  576.    }
  577.  
  578. SetAPen(mywindow->RPort,3);
  579. RectFill(mywindow->RPort,cx-7,cy-6,cx,cy+1);
  580. SetAPen(mywindow->RPort,1);
  581. }
  582. /*************************************************
  583. *  function to take raw key data and convert it 
  584. *  into ascii chars
  585. **************************************************/
  586. toasc(code)
  587. USHORT code;
  588. {
  589. static int ctrl = FALSE;
  590. static int shift = FALSE;
  591. static int capsl = FALSE;
  592. char c;
  593. static char keys[75] = {
  594. '`' , '1' , '2' , '3' , '4' , '5' , '6' , '7' , '8' , '9' , '0' , '-' ,
  595. '=' , '\\' , 0 , '0' , 'q' , 'w' , 'e' , 'r' , 't' , 'y' , 'u' , 'i' , 'o' ,
  596. 'p' , '[' , ']' , 0 , '1' , '2' , '3' , 'a' , 's' , 'd' , 'f' , 'g' , 'h' ,
  597. 'j' , 'k' , 'l' , ';' , '\'' , 0 , 0 , '4' , '5' , '6' , 0 , 'z' , 'x' , 'c' , 'v' ,
  598. 'b' , 'n' , 'm' , 44 , '.' , '/' , 0 , '.' , '7' , '8' , '9' , ' ' , 8 ,
  599. '\t' , 13 , 13 , 27 , 127 , 0 , 0 , 0 , '-' } ;
  600.  
  601.              switch ( code ) /* I didn't know about the Quilifier field when I write this */
  602.                     {
  603.                     case 98:
  604.                        capsl = TRUE;
  605.                        c = 0;
  606.                        break;
  607.                     case 226:
  608.                        capsl , "do explicit test for CNTRL-C");
  609.     DISABLE_ABORT;
  610.     if (Chk_Abort () != 0) {
  611.         if (Vflag) {
  612.             printf ("cc - terminated by request\n");
  613.         }
  614.         exit (1);
  615.     }
  616.     ENABLE_ABORT;
  617. #endif
  618.     DBUG_VOID_RETURN;
  619. }
  620.  
  621.